package com.eastedu.superise.handler.question.handler.answerparentheses.underline;

import com.eastedu.common.enums.MediaTypeEnum;
import com.eastedu.common.model.question.Fragment;
import com.eastedu.common.model.question.QuestionItemContent;
import com.eastedu.superise.handler.question.handler.ContentConverter;
import com.eastedu.superise.handler.question.handler.PatternConstant;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;

/**
 * Stem content converter.
 *
 * @author Administrator
 */
public class StemUnderlineContentConverter implements ContentConverter {

    @Override
    public void convert(List<QuestionItemContent> contents) {
        for (QuestionItemContent itemContent : contents) {
            List<Fragment> newFragments = new ArrayList<>();
            List<Fragment> fragments = itemContent.getFragments();
            for (Fragment fragment : fragments) {
                if (fragment.getMediaType() == MediaTypeEnum.FORMULA) {
                    newFragments.add(fragment);
                    continue;
                }
                String content = fragment.getContent();
                // 分隔内容，并保留分隔符
                String[] split = content.split(PatternConstant.SPIT_WITH_PARENTHESES_UNDERLINE_AND_KEEP_SEPARATOR);
                for (String piece : split) {
                    if (StringUtils.isEmpty(piece)) {
                        continue;
                    }
                    // 根据内容转换出分隔符，为空则为普通内容（这里是全匹配，不是find）
                    SeparateSymbol separateSymbol = SeparateSymbol.getByContent(piece);
                    // 必须是下划线才行
                    if (separateSymbol == SeparateSymbol.PARENTHESES_BLANK) {
                        if (fragment.getStyles().contains("UnderlineSingle")) {
                            separateSymbol = SeparateSymbol.PARENTHESES_UNDERLINE;
                        } else {
                            separateSymbol = SeparateSymbol.NORMAL;
                        }
                    }

                    BiFunction<Fragment, String, Fragment> function = separateSymbol.getFunction();
                    Fragment f1 = function.apply(fragment, piece);
                    newFragments.add(f1);

                    if (separateSymbol != SeparateSymbol.NORMAL) {
                        // 非普通内容，后面追加空字符串文本， 为了兼容前端编辑器鼠标定位问题
                        Fragment e = Fragment.copyWithoutContent(fragment, false);
                        e.setMediaType(MediaTypeEnum.TEXT);
                        e.setContent("");
                        newFragments.add(e);
                    }
                }
            }
            itemContent.setFragments(newFragments);
        }
    }

    /**
     * The enum Separate symbol.
     */
    @Getter
    enum SeparateSymbol {
        /**
         * 空格匹配
         */
        PARENTHESES_BLANK(PatternConstant.ANSWER_PARENTHESES_BLANK_REGX, SeparateSymbol::createParenthesesFragment),
        /**
         * 下划线匹配
         */
        PARENTHESES_UNDERLINE(PatternConstant.ANSWER_PARENTHESES_UNDERLINE_REGX, SeparateSymbol::createParenthesesFragment),
        /**
         * 普通内容.
         */
        NORMAL("", SeparateSymbol::createNormalFragment);


        /**
         * 全匹配正则
         */
        private final String regEx;
        private final BiFunction<Fragment, String, Fragment> function;

        SeparateSymbol(String regEx, BiFunction<Fragment, String, Fragment> function) {
            this.regEx = regEx;
            this.function = function;
        }

        private static Fragment createParenthesesFragment(Fragment fragment, String space) {
            Fragment f1 = Fragment.copyWithoutContent(fragment, false);
            f1.setContent("        ");
            f1.setMediaType(MediaTypeEnum.STRUCTURE);
            // 中文括号
            f1.getStyles().add("cnBrackets");
            // 结构化括号标识（可编辑样式）
            f1.getStyles().add("structureBracket");
            return f1;
        }

        private static Fragment createNormalFragment(Fragment fragment, String content) {
            Fragment f1 = Fragment.copyWithoutContent(fragment, true);
            f1.setContent(content);
            return f1;
        }

        /**
         * 根据内容匹配获取枚举.
         *
         * @param content the content
         * @return the by content
         */
        public static SeparateSymbol getByContent(String content) {
            for (SeparateSymbol symbol : values()) {
                if (symbol.match(content)) {
                    return symbol;
                }
            }
            return NORMAL;
        }

        /**
         * 内容是否匹配.
         *
         * @param content the content
         * @return the boolean
         */
        public boolean match(String content) {
            return content.matches(this.regEx);
        }

    }


}
